#pragma once
#include <memory>
#include <functional>
#include <atomic>
#include <mutex>
#include <iostream>
#include <vector>

#include "CurrentThread.h"
#include "Timestamp.h"

class Channel;
class Poller;

class EventLoop
{

public:
    using Functor = std::function<void()>;

    EventLoop();
    ~EventLoop();

    void loop(); //开启事件循环
    void quit(); // 退出事件循环

    Timestamp pollReturnTime() const{ return pollReturnTime_; }

    void runInLoop(Functor cb); //在当前loop中执行cb
    void queueInLoop(Functor cb); //将cb放入队列中，唤醒loop所在线程去执行

    void wakeup(); // 唤醒loop所在线程

    // 调用的poller函数
    void updateChannel(Channel *channel);
    void removeChannel(Channel *channel);
    void hasChannel(Channel *channel);

    // 判断当前loop对象是否在自己的线程里
    bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); }

private:
    void handleRead(); // wake up
    void doPendingFunctors(); // 执行回调

    using ChannelList = std::vector<Channel *>;

    std::atomic_bool looping_; // 原子操作
    std::atomic_bool quit_;    // 标识退出loop循环

    const pid_t threadId_; // 记录当前loop所在的线程id

    Timestamp pollReturnTime_;       // poller返回发生事件的channels的时间点
    std::unique_ptr<Poller> poller_; // 对应的poller

    int wakeupfd_; // 唤醒
    std::unique_ptr<Channel> wakeupChannel_;

    ChannelList activeCHannels_; // 管理的所有channel
    // Channel *currentActiveChannel_;

    std::atomic_bool callingPendingFunctors_; // 标识当前loop是否需要回调
    std::vector<Functor> pendingFunctors_;    // 存储loop需要执行的所有回调操作
    std::mutex mutex_;                        // 互斥锁，报错vector的线程安全操作
};